package org.mtmi.ui.scenes.actions;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.graphics.Rectangle;
import org.mtmi.ui.GraphicUtil;
import org.mtmi.ui.IMG;
import org.mtmi.ui.actions.Action;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.listeners.ISelectionListener;
import org.mtmi.ui.controls.listeners.SelectionEvent;
import org.mtmi.ui.drawables.IDrawable;
import org.mtmi.ui.scenes.ISceneManagerListener;
import org.mtmi.ui.scenes.Scene;
import org.mtmi.ui.scenes.SceneManager;

/**
 * This action is made to change the Z order of selected controls of a scene..
 * It's enabled when there are at least one control overlapping one of selected controls.
 */
public class ZOrderAction extends Action
  implements ISceneManagerListener, ISelectionListener
{
	private Scene scene;
	private ArrayList<Control> z_stack; // the Z stack.
	
	public ZOrderAction() {
		super( PUSH );
		
		z_stack = new ArrayList<Control>();
		//TODO: this must be removed also ... but miss dispose() in IAction.		
		SceneManager.getDefault().addSceneManagerListener( this );
		scene = SceneManager.getDefault().getScene();
		scene.addSelectionListener( this );
		
	}

	@Override
	public IDrawable getImage() { return IMG.GetD( IMG.I_Z_ORDER ); }

	@Override
	public boolean isEnabled() {
		return z_stack.size()>1;
	}
	
	/** update z_stack order. */
	private void sceneSelectionChanged() 
	{
		z_stack = GetZStackFor( scene );
		update();
	}
	
	/** update z_stack order. */
	public static ArrayList<Control> GetZStackFor( Scene scene ) 
	{
		ArrayList<Control> z_stack = new ArrayList<Control>();
		List<Control> sc = scene.getSelection();
		
		if( scene.hasSelection() ) {
		
			//collect bounds to check overlap:
			ArrayList<Rectangle> bounds = new ArrayList<Rectangle>( sc.size() );
			for( Control d : sc ) {
				bounds.add( d.getBounds(  null ) );
			}
			//check overlap: (assuming all control comes from same scene
			Rectangle b=null;
			for( Control x : scene.getControls( false ) ) {
				if( sc.contains( x ) ) {
					z_stack.add( x );
				} else {
					b = x.getBounds( b );
					for( Rectangle r : bounds ) {
						if( GraphicUtil.rectOverlap( r, b ) ) {
							z_stack.add( x );
							break;
						}
					}
				}
			}
		}
/*debug: System.out.println(" Z stack for last selected control (btm 2 up):");
for( Control x : z_stack ) {
	System.out.println("   "+x);
}*/
        return z_stack;
	}
	
	/** called by scene */
	public void sceneControlBoundsChanged() {
		sceneSelectionChanged();
	}
	
	@Override
	public void run() {
		scene.setEditMode( Scene.EDIT_Z_STACK );
	}
	
	@Override
	public void sceneManagerModeChanged(boolean edit) {}

	@Override
	public void sceneManagerSceneChanged( Scene new_scene, Scene old_scene )
	{
		if( old_scene!=null ) old_scene.removeSelectionListener( this );
		scene = new_scene;
		scene.addSelectionListener( this );
		sceneSelectionChanged();
	}

	@Override
	public void sceneManagerSceneAdded(Scene sceneAdded) {}
	
	@Override
	public void sceneManagerSceneRemoved(Scene sceneRemoved) {}

	@Override
	public void selectionChanged( SelectionEvent e ) {
		sceneSelectionChanged();
	}
	
	@Override
	public void selectionConfirmed(SelectionEvent e) {}

}
